//#include "lspmessage.pb-c.h"
//*********************************************
//ADRIAN SALAZAR && JUSTIN MICHALE SCHWARTZBECK
//HOMEWORK 2
//FEB. 23, 2012
//
//lsp.c 	API shell that is used to provide
//		consistency
//*********************************************
#include "lsp.h"

//Default Variables
double epoch_lth = _EPOCH_LTH;
int epoch_cnt = _EPOCH_CNT;
double drop_rate = _DROP_RATE;

/*
 *
 *
 *				LSP RELATED FUNCTIONS
 *
 *
 */  

void lsp_set_epoch_lth(double lth){epoch_lth = lth;}
void lsp_set_epoch_cnt(int cnt){epoch_cnt = cnt;}
void lsp_set_drop_rate(double rate){drop_rate = rate;}
 

/*
 *
 *
 *				CLIENT RELATED FUNCTIONS
 *
 
 */  

//Create a new instance of the client
lsp_client* lsp_client_create(const char* src, int port)
{

	//Create a new client connection
	lsp_client * new_client = (lsp_client *) new uint8_t[sizeof(lsp_client)];
	
	//set the default variables
	new_client->client = new ClientBuffer(src, port, epoch_lth, epoch_cnt, drop_rate);
	new_client->success = new_client->client->state;
	return new_client;
}

//Read from the client
int lsp_client_read(lsp_client* a_client, uint8_t* pld)
{
	int lenght;
	lenght = a_client->client->read((uint8_t*)pld);
	return lenght; 
		
}

//Write to the client
bool lsp_client_write(lsp_client* a_client, uint8_t* pld, int lth)
{

	int res = a_client->client->write((uint8_t*)pld, (uint32_t)lth);
	return true;
	
}
//Terminate connection
bool lsp_client_close(lsp_client* a_client)
{
	a_client->client->finish();
	return true;
}

//Check to see if the client is running
bool lsp_client_alive(lsp_client* a_client)
{
	return a_client->client->is_running();
}

/*
 *
 *
 *				SERVER RELATED FUNCTIONS
 *
 *
 */  


lsp_server* lsp_server_create(int port)
{
	lsp_server *serv = (lsp_server*) new uint8_t[sizeof(lsp_server)];
	serv->server = new ServerBuffer(port, epoch_lth, epoch_cnt);
	serv->success = serv->server->state;
	return serv;
}

int lsp_server_read(lsp_server* a_srv, void* pld, uint32_t* conn_id)
{
	int result = a_srv->server->read((uint8_t*)pld, conn_id);
	/*uint32_t c_id = 0;
	int result = 0;
	std::list<ClientData*>::iterator client = a_srv->server->connected_clients.begin();
	pthread_mutex_lock(&(a_srv->server->client_lock));
	while(client != a_srv->server->connected_clients.end() &&
		(*client)->in_buf.size() == 0) {
		client++;
	}
	if(client != a_srv->server->connected_clients.end()) {
		c_id = (*client)->conn_id;
		result = a_srv->server->read(c_id, (uint8_t*)pld);
	}
	pthread_mutex_unlock(&(a_srv->server->client_lock));
	*conn_id = c_id;*/
	return result;
}

bool lsp_server_write(lsp_server* a_srv, void* pld, int lth, uint32_t conn_id)
{
	int result = a_srv->server->write(conn_id, (uint8_t*)pld, lth);
	return result == -1;
}

bool lsp_server_close(lsp_server* a_srv, uint32_t conn_id)
{
	std::list<ClientData*>::iterator conn = 
		a_srv->server->connected_clients.begin();
	while(conn != a_srv->server->connected_clients.end() &&
		(*conn)->conn_id != conn_id)
		conn++;
	if(conn != a_srv->server->connected_clients.end()) {
		pthread_mutex_lock(&(a_srv->server->client_lock));
		a_srv->server->connected_clients.erase(conn);
		pthread_mutex_unlock(&(a_srv->server->client_lock));
		return true;
	}
	return false;
}
